﻿using System;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Gqq.Csharpindepth.Basic;
using Gqq.Csharpindepth.Chapter1;
using Gqq.Csharpindepth.Common;
//命名空间的别名
using Gqq.Csharpindepth.Designpatter;
using Chapter4 = Gqq.Csharpindepth.Chapter456;

namespace Gqq.Csharpindepth
{
    extern alias SubCommon;

    class Program
    {
        static void Main()
        {
           
            #region Methods

//            SubFriendTest.TestInfo();
//            ExecuteClass.Test();
            // Console.WriteLine("Hello World!");
            //TestProduct();
            //            TestStorageAndProduct();
            //ReadXmlByLinq();
            //DetailsTest();

     
            //            new Chapter4.Chapter456Test();
            //            Box.TestResult();
            //Test23Class.Test();
            //FileProcess.Test();
//            CommonTest.Test();
//            DataStructureTest.DoTest();
            PatternTest.Test();

           // TestAttributes.DoTest();
            #endregion


            Console.ReadKey();
        }

        #region Chapter1
        /// <summary>
        /// 测试Product类
        /// </summary>
        static void TestProduct()
        {
            var pLists = Product.GetSampleLists();

            foreach (var source in pLists.WhereGqq(p => !p.Name.StartsWith("x")))
            {
                Console.WriteLine(source);
            }

            foreach (var source in pLists.WhereGqq(p => p.Id, 6))
            {
                Console.WriteLine(source);
            }
            //plists没有改变
            //            pLists.ForEach(Console.WriteLine);
            Console.WriteLine("**********************************************************************");
            //pLists.Sort(new ListCompare());
            //            pLists.Sort()

            //public delegate int Comparison<in T>(T x, T y)
            //这个是委托Comparison的定义。
            pLists.Sort((x, y) => (x.Id.CompareTo(y.Id)));

            //当然，也可以用一下方式(C#2.0 的写法)
            //传入的参数正是通过什么方法来比较大小。
            pLists.Sort(delegate(Product x, Product y) { return x.Id.CompareTo(y.Id); });
            int maxId = pLists.Max(x => x.Id);
            //pLists.Max()
            string maxName = pLists.Max(x => x.Name);
            Console.WriteLine(maxName);
            Console.WriteLine(maxId);

            //在ForEach中，参数是一个委托，而委托的参数正是Product
            pLists.ForEach(Product.Output);

            pLists.ForEach(x => Console.WriteLine(x));
            //本质就是
            pLists.ForEach(delegate(Product p) { Console.WriteLine(p); });
            //更深入的理解便是
            Action<Product> ap = delegate(Product p) { Console.WriteLine(p); };
            pLists.ForEach(ap);

            //也可以写作如下。
            //            pLists.ForEach(Console.WriteLine);

            //测试arraylist的sort方法。
            var alists = Product.GetSampleArrLists();
            //默认排序(c# 1.0弱爆了)
            //            alists.Sort(new ProductCompare());
            alists.Sort(new ArraylistCompare());
            foreach (var alist in alists)
            {
                Console.WriteLine(alist);
            }

        }

        /// <summary>
        /// 测试使用Linq实现两个列表的连接。
        /// </summary>
        static void TestStorageAndProduct()
        {
            var products = Product.GetSampleLists();
            var stores = Storage.GetStorageLists();
            var infos = from pd in products
                        join st in stores
                            on pd.StorageId equals st.StorageId
                        orderby pd.Id
                        //做出关联之后，放入一个类当中去。
                        select
                            new ProductAndStore
                                {
                                    ProductId = pd.Id,
                                    ProductName = pd.Name,
                                    StoreName = st.StorageName,
                                    StorageId = st.StorageId
                                };
            foreach (var ps in infos)
            {
                Console.WriteLine(ps);
            }


        }

        /// <summary>
        /// 使用Linq读取Xml
        /// </summary>
        public static void ReadXmlByLinq()
        {
            XDocument doc = XDocument.Load("Chapter1\\PSConfig.xml");
            var query = from pr in doc.Descendants("Product")
                        join st in doc.Descendants("Store")
                            on (int)pr.Attribute("StoreId") equals (int)st.Attribute("Id")
                        orderby (int)pr.Attribute("Id") descending
                        select
                            new
                                {
                                    ProductId = (int)pr.Attribute("Id"),
                                    ProductName = (string)pr.Attribute("Name"),
                                    StoreId = (int)pr.Attribute("StoreId"),
                                    StoreName = (string)st.Attribute("Name")
                                };
            foreach (var info in query)
            {
                Console.WriteLine("{0}-{1}-{2}-{3}", info.ProductId, info.ProductName, info.StoreId, info.StoreName);
            }
        }

        /// <summary>
        /// 关于参数传递的是引用的值的例子。
        /// </summary>
        public static void DetailsTest()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("aa ");
            sb.Append("bb ");
            //其实,null也可以作为参数传递，传递的只是null引用的值。
            //            Details.TestStringBuilder(null);
            //其实，传递的参数是值和sb相等的另外一个指针，并非是sb指针本身。
            //所以，在函数TestStringBuilder中改变了实参的指向情况后，出了函数
            //sb的值依然没有改变。这点要特别注意。
            Details.TestStringBuilder(sb);
            Console.WriteLine(sb.ToString());
        }

        #endregion

        #region Chapter4

        /// <summary>
        /// 测试命名空间。
        /// </summary>
        public static void TestNameSpace()
        {
            //VarianceAndContravariance.Test();
            var t = new global::Chapter4.Chapter456Test2();
            Chapter4::Chapter456Test.Test();
            var t2 = new global::Chapter456Test(3);
        }

        #endregion
    }


}
